package com.cencat.dispatch.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.dispatch.entity.Dispatch;
import com.cencat.dispatch.mapper.DispatchMapper;
import com.cencat.dispatch.service.DispatchService;
import com.cencat.dispatch.vo.DispatchVO;
import com.cencat.dispatch.dto.DispatchDTO;
import com.cencat.dispatch.dto.DispatchQueryDTO;
import com.cencat.dispatch.dto.DispatchBatchUpdateDTO;
import com.cencat.dispatch.dto.DispatchStatisticsDTO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 调度管理服务实现类
 * 提供调度的增删改查、统计分析、智能匹配等功能的具体实现
 * 
 * @author cencat
 * @version 1.0
 * @since 2025-01-20
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DispatchServiceImpl implements DispatchService {

    @Autowired
    private DispatchMapper dispatchMapper;

    @Override
    public Page<DispatchVO> getDispatchList(Page<Dispatch> page, DispatchQueryDTO queryDTO) {
        Page<Dispatch> dispatchPage = dispatchMapper.selectDispatchPage(page, queryDTO);
        Page<DispatchVO> voPage = new Page<>(dispatchPage.getCurrent(), dispatchPage.getSize(), dispatchPage.getTotal());
        
        List<DispatchVO> voList = dispatchPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        
        return voPage;
    }

    @Override
    public DispatchVO getDispatchById(Long id) {
        Dispatch dispatch = dispatchMapper.selectById(id);
        return dispatch != null ? convertToVO(dispatch) : null;
    }

    @Override
    public Boolean createDispatch(DispatchDTO dispatchDTO) {
        // 检查调度编号是否已存在
        if (existsByDispatchNo(dispatchDTO.getDispatchNo(), null)) {
            throw new RuntimeException("调度编号已存在: " + dispatchDTO.getDispatchNo());
        }
        
        Dispatch dispatch = convertToEntity(dispatchDTO);
        dispatch.setCreateTime(LocalDateTime.now());
        dispatch.setUpdateTime(LocalDateTime.now());
        
        return dispatchMapper.insert(dispatch) > 0;
    }

    @Override
    public Boolean updateDispatch(Long id, DispatchDTO dispatchDTO) {
        Dispatch existingDispatch = dispatchMapper.selectById(id);
        if (existingDispatch == null) {
            throw new RuntimeException("调度不存在: " + id);
        }
        
        // 检查调度编号是否已存在（排除当前记录）
        if (existsByDispatchNo(dispatchDTO.getDispatchNo(), id)) {
            throw new RuntimeException("调度编号已存在: " + dispatchDTO.getDispatchNo());
        }
        
        Dispatch dispatch = convertToEntity(dispatchDTO);
        dispatch.setId(id);
        dispatch.setUpdateTime(LocalDateTime.now());
        
        return dispatchMapper.updateById(dispatch) > 0;
    }

    @Override
    public Boolean deleteDispatch(Long id) {
        Dispatch dispatch = dispatchMapper.selectById(id);
        if (dispatch == null) {
            throw new RuntimeException("调度不存在: " + id);
        }
        
        return dispatchMapper.deleteById(id) > 0;
    }

    @Override
    public Boolean batchDeleteDispatches(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        
        return dispatchMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean batchUpdateDispatchStatus(DispatchBatchUpdateDTO batchUpdateDTO) {
        if (CollectionUtils.isEmpty(batchUpdateDTO.getIds())) {
            return false;
        }
        
        return dispatchMapper.batchUpdateDispatchStatus(
                batchUpdateDTO.getIds(), 
                batchUpdateDTO.getStatus()
        ) > 0;
    }

    @Override
    public Boolean batchUpdatePriority(List<Long> ids, Integer priority) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        
        return dispatchMapper.batchUpdatePriority(ids, priority) > 0;
    }

    @Override
    public Boolean batchAssignDriver(List<Long> ids, Long driverId) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        
        return dispatchMapper.batchAssignDriver(ids, driverId) > 0;
    }

    @Override
    public Boolean batchAssignVehicle(List<Long> ids, Long vehicleId) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        
        return dispatchMapper.batchAssignVehicle(ids, vehicleId) > 0;
    }

    @Override
    public Map<String, Object> getDispatchStatistics(DispatchStatisticsDTO statisticsDTO) {
        Map<String, Object> result = new HashMap<>();
        
        // 总调度数
        Long totalCount = dispatchMapper.selectCount(null);
        result.put("totalCount", totalCount);
        
        // 待分配调度数
        Long pendingCount = dispatchMapper.countByStatus("PENDING");
        result.put("pendingCount", pendingCount);
        
        // 进行中调度数
        Long inProgressCount = dispatchMapper.countByStatus("IN_PROGRESS");
        result.put("inProgressCount", inProgressCount);
        
        // 已完成调度数
        Long completedCount = dispatchMapper.countByStatus("COMPLETED");
        result.put("completedCount", completedCount);
        
        // 已取消调度数
        Long cancelledCount = dispatchMapper.countByStatus("CANCELLED");
        result.put("cancelledCount", cancelledCount);
        
        // 暂停调度数
        Long pausedCount = dispatchMapper.countByStatus("PAUSED");
        result.put("pausedCount", pausedCount);
        
        return result;
    }

    @Override
    public List<DispatchVO> getPendingDispatches(Integer limit) {
        List<Dispatch> dispatches = dispatchMapper.selectPendingDispatches(limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> getInProgressDispatches(Integer limit) {
        List<Dispatch> dispatches = dispatchMapper.selectInProgressDispatches(limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> getCompletedDispatches(Integer limit) {
        List<Dispatch> dispatches = dispatchMapper.selectCompletedDispatches(limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> getHighPriorityDispatches(Integer minPriority, Integer limit) {
        List<Dispatch> dispatches = dispatchMapper.selectHighPriorityDispatches(minPriority, limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> getUrgentDispatches(Integer limit) {
        List<Dispatch> dispatches = dispatchMapper.selectUrgentDispatches(limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> getDispatchesByDriver(Long driverId, String status, Integer limit) {
        List<Dispatch> dispatches = dispatchMapper.selectDispatchesByDriver(driverId, status, limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> getDispatchesByVehicle(Long vehicleId, String status, Integer limit) {
        List<Dispatch> dispatches = dispatchMapper.selectDispatchesByVehicle(vehicleId, status, limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> getDispatchesByRoute(Long routeId, String status, Integer limit) {
        List<Dispatch> dispatches = dispatchMapper.selectDispatchesByRoute(routeId, status, limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> getDispatchesByTimeRange(LocalDateTime startTime, LocalDateTime endTime, Integer limit) {
        List<Dispatch> dispatches = dispatchMapper.selectDispatchesByTimeRange(startTime, endTime, limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> getDispatchesByOrigin(String originCity, String status, Integer limit) {
        List<Dispatch> dispatches = dispatchMapper.selectDispatchesByOrigin(originCity, status, limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> getDispatchesByDestination(String destinationCity, String status, Integer limit) {
        List<Dispatch> dispatches = dispatchMapper.selectDispatchesByDestination(destinationCity, status, limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> intelligentMatchDispatches(String requirements, Integer limit) {
        // 智能匹配调度逻辑
        List<Dispatch> dispatches = dispatchMapper.selectIntelligentMatchDispatches(requirements, limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public Boolean existsById(Long id) {
        return dispatchMapper.selectById(id) != null;
    }

    @Override
    public Boolean existsByDispatchNo(String dispatchNo, Long excludeId) {
        return dispatchMapper.existsByDispatchNo(dispatchNo, excludeId) > 0;
    }

    @Override
    public Boolean assignDriver(Long dispatchId, Long driverId, String reason) {
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            throw new RuntimeException("调度不存在: " + dispatchId);
        }
        
        dispatch.setDriverId(driverId);
        dispatch.setUpdateTime(LocalDateTime.now());
        
        return dispatchMapper.updateById(dispatch) > 0;
    }

    @Override
    public Boolean assignVehicle(Long dispatchId, Long vehicleId, String reason) {
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            throw new RuntimeException("调度不存在: " + dispatchId);
        }
        
        dispatch.setVehicleId(vehicleId);
        dispatch.setUpdateTime(LocalDateTime.now());
        
        return dispatchMapper.updateById(dispatch) > 0;
    }

    @Override
    public Boolean assignRoute(Long dispatchId, Long routeId, String reason) {
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            throw new RuntimeException("调度不存在: " + dispatchId);
        }
        
        dispatch.setRouteId(routeId);
        dispatch.setUpdateTime(LocalDateTime.now());
        
        return dispatchMapper.updateById(dispatch) > 0;
    }

    @Override
    public Boolean startDispatch(Long dispatchId, String startReason) {
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            throw new RuntimeException("调度不存在: " + dispatchId);
        }
        
        dispatch.setStatus("IN_PROGRESS");
        dispatch.setStartTime(LocalDateTime.now());
        dispatch.setUpdateTime(LocalDateTime.now());
        
        return dispatchMapper.updateById(dispatch) > 0;
    }

    @Override
    public Boolean completeDispatch(Long dispatchId, String completionNotes) {
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            throw new RuntimeException("调度不存在: " + dispatchId);
        }
        
        dispatch.setStatus("COMPLETED");
        dispatch.setEndTime(LocalDateTime.now());
        dispatch.setUpdateTime(LocalDateTime.now());
        
        return dispatchMapper.updateById(dispatch) > 0;
    }

    @Override
    public Boolean cancelDispatch(Long dispatchId, String cancelReason) {
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            throw new RuntimeException("调度不存在: " + dispatchId);
        }
        
        dispatch.setStatus("CANCELLED");
        dispatch.setUpdateTime(LocalDateTime.now());
        
        return dispatchMapper.updateById(dispatch) > 0;
    }

    @Override
    public Boolean pauseDispatch(Long dispatchId, String pauseReason) {
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            throw new RuntimeException("调度不存在: " + dispatchId);
        }
        
        dispatch.setStatus("PAUSED");
        dispatch.setUpdateTime(LocalDateTime.now());
        
        return dispatchMapper.updateById(dispatch) > 0;
    }

    @Override
    public Boolean resumeDispatch(Long dispatchId, String resumeReason) {
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            throw new RuntimeException("调度不存在: " + dispatchId);
        }
        
        dispatch.setStatus("IN_PROGRESS");
        dispatch.setUpdateTime(LocalDateTime.now());
        
        return dispatchMapper.updateById(dispatch) > 0;
    }

    @Override
    public Boolean updateDispatchPriority(Long dispatchId, Integer priority, String reason) {
        return dispatchMapper.updateDispatchPriority(dispatchId, priority, reason) > 0;
    }

    @Override
    public Boolean updateDispatchSchedule(Long dispatchId, LocalDateTime scheduledTime, String reason) {
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            throw new RuntimeException("调度不存在: " + dispatchId);
        }
        
        dispatch.setScheduledTime(scheduledTime);
        dispatch.setUpdateTime(LocalDateTime.now());
        
        return dispatchMapper.updateById(dispatch) > 0;
    }

    @Override
    public Boolean updateDispatchLocation(Long dispatchId, String currentLocation) {
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            throw new RuntimeException("调度不存在: " + dispatchId);
        }
        
        dispatch.setCurrentLocation(currentLocation);
        dispatch.setUpdateTime(LocalDateTime.now());
        
        return dispatchMapper.updateById(dispatch) > 0;
    }

    @Override
    public Map<String, Object> getDispatchPerformance(Long dispatchId, LocalDateTime startTime, LocalDateTime endTime) {
        Map<String, Object> result = new HashMap<>();
        
        // 获取调度绩效数据
        result.put("dispatchId", dispatchId);
        result.put("period", startTime + " - " + endTime);
        result.put("totalTasks", 0);
        result.put("completedTasks", 0);
        result.put("cancelledTasks", 0);
        result.put("averageCompletionTime", 0.0);
        result.put("onTimeRate", 0.0);
        result.put("efficiency", 0.0);
        
        return result;
    }

    @Override
    public Double calculateDispatchDistance(Long dispatchId) {
        // 计算调度距离逻辑
        return dispatchMapper.calculateDispatchDistance(dispatchId);
    }

    @Override
    public Integer estimateDispatchDuration(Long dispatchId) {
        // 估算调度时长逻辑
        return dispatchMapper.estimateDispatchDuration(dispatchId);
    }

    @Override
    public BigDecimal calculateDispatchCost(Long dispatchId) {
        // 计算调度成本逻辑
        return dispatchMapper.calculateDispatchCost(dispatchId);
    }

    @Override
    public List<DispatchVO> recommendDispatches(Long driverId, String preferences, Integer limit) {
        // 推荐调度逻辑
        List<Dispatch> dispatches = dispatchMapper.selectRecommendedDispatches(driverId, preferences, limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> searchDispatches(String keyword, String searchType, Integer limit) {
        List<Dispatch> dispatches = dispatchMapper.searchDispatches(keyword, searchType, limit);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DispatchVO> exportDispatches(DispatchQueryDTO queryDTO) {
        List<Dispatch> dispatches = dispatchMapper.selectDispatchList(queryDTO);
        return dispatches.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public Boolean importDispatches(List<DispatchDTO> dispatches) {
        if (CollectionUtils.isEmpty(dispatches)) {
            return false;
        }
        
        for (DispatchDTO dispatchDTO : dispatches) {
            try {
                createDispatch(dispatchDTO);
            } catch (Exception e) {
                // 记录导入失败的记录
                System.err.println("导入调度失败: " + dispatchDTO.getDispatchNo() + ", 原因: " + e.getMessage());
            }
        }
        
        return true;
    }

    @Override
    public Boolean syncDispatchData(Long dispatchId, String syncType) {
        // 调度数据同步逻辑
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            return false;
        }
        
        // 根据同步类型执行不同的同步逻辑
        switch (syncType) {
            case "STATUS":
                // 同步状态信息
                break;
            case "LOCATION":
                // 同步位置信息
                break;
            case "SCHEDULE":
                // 同步调度信息
                break;
            default:
                // 全量同步
                break;
        }
        
        return true;
    }

    @Override
    public Boolean batchSyncDispatchData(List<Long> dispatchIds, String syncType) {
        if (CollectionUtils.isEmpty(dispatchIds)) {
            return false;
        }
        
        for (Long dispatchId : dispatchIds) {
            syncDispatchData(dispatchId, syncType);
        }
        
        return true;
    }

    @Override
    public Boolean optimizeDispatch(Long dispatchId, String optimizationType) {
        // 调度优化逻辑
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            return false;
        }
        
        // 根据优化类型执行不同的优化逻辑
        switch (optimizationType) {
            case "ROUTE":
                // 路线优化
                break;
            case "TIME":
                // 时间优化
                break;
            case "COST":
                // 成本优化
                break;
            default:
                // 综合优化
                break;
        }
        
        return true;
    }

    @Override
    public Boolean batchOptimizeDispatches(List<Long> dispatchIds, String optimizationType) {
        if (CollectionUtils.isEmpty(dispatchIds)) {
            return false;
        }
        
        for (Long dispatchId : dispatchIds) {
            optimizeDispatch(dispatchId, optimizationType);
        }
        
        return true;
    }

    @Override
    public Boolean autoAssignDispatch(Long dispatchId, String assignmentStrategy) {
        // 自动分配调度逻辑
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            return false;
        }
        
        // 根据分配策略执行不同的分配逻辑
        switch (assignmentStrategy) {
            case "NEAREST_DRIVER":
                // 最近司机分配
                break;
            case "BEST_MATCH":
                // 最佳匹配分配
                break;
            case "LOAD_BALANCE":
                // 负载均衡分配
                break;
            default:
                // 默认分配策略
                break;
        }
        
        return true;
    }

    @Override
    public Boolean batchAutoAssignDispatches(List<Long> dispatchIds, String assignmentStrategy) {
        if (CollectionUtils.isEmpty(dispatchIds)) {
            return false;
        }
        
        for (Long dispatchId : dispatchIds) {
            autoAssignDispatch(dispatchId, assignmentStrategy);
        }
        
        return true;
    }

    @Override
    public Map<String, Object> getDispatchAnalytics(LocalDateTime startTime, LocalDateTime endTime, String analyticsType) {
        Map<String, Object> result = new HashMap<>();
        
        // 获取调度分析数据
        result.put("period", startTime + " - " + endTime);
        result.put("analyticsType", analyticsType);
        result.put("totalDispatches", 0);
        result.put("completionRate", 0.0);
        result.put("averageResponseTime", 0.0);
        result.put("peakHours", new ArrayList<>());
        result.put("topRoutes", new ArrayList<>());
        result.put("driverPerformance", new ArrayList<>());
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getDispatchTrends(LocalDateTime startTime, LocalDateTime endTime, String trendType) {
        // 获取调度趋势数据
        return dispatchMapper.selectDispatchTrends(startTime, endTime, trendType);
    }

    @Override
    public Boolean validateDispatch(Long dispatchId, String validationType) {
        // 调度验证逻辑
        Dispatch dispatch = dispatchMapper.selectById(dispatchId);
        if (dispatch == null) {
            return false;
        }
        
        // 根据验证类型执行不同的验证逻辑
        switch (validationType) {
            case "DRIVER_AVAILABILITY":
                // 验证司机可用性
                break;
            case "VEHICLE_STATUS":
                // 验证车辆状态
                break;
            case "ROUTE_FEASIBILITY":
                // 验证路线可行性
                break;
            default:
                // 全面验证
                break;
        }
        
        return true;
    }

    @Override
    public Boolean batchValidateDispatches(List<Long> dispatchIds, String validationType) {
        if (CollectionUtils.isEmpty(dispatchIds)) {
            return false;
        }
        
        for (Long dispatchId : dispatchIds) {
            if (!validateDispatch(dispatchId, validationType)) {
                return false;
            }
        }
        
        return true;
    }

    /**
     * 将Dispatch实体转换为DispatchVO
     */
    private DispatchVO convertToVO(Dispatch dispatch) {
        if (dispatch == null) {
            return null;
        }
        
        DispatchVO vo = new DispatchVO();
        BeanUtils.copyProperties(dispatch, vo);
        return vo;
    }

    /**
     * 将DispatchDTO转换为Dispatch实体
     */
    private Dispatch convertToEntity(DispatchDTO dto) {
        if (dto == null) {
            return null;
        }
        
        Dispatch entity = new Dispatch();
        BeanUtils.copyProperties(dto, entity);
        return entity;
    }
}